/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.drawee.drawable;

import com.facebook.imagepipeline.annotation.NonNull;
import com.facebook.imagepipeline.annotation.Nullable;
import com.oszc.bbhmlibrary.utils.LogUtil;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.ColorFilter;
import ohos.agp.render.ColorMatrix;
import ohos.agp.utils.Rect;
import ohos.app.Context;

import java.lang.ref.WeakReference;
import java.util.Arrays;

/**
 *  add some ability that the system don't have
 */
public abstract class RootShapeElement extends ShapeElement implements LevelElement {
    private final String TAG = RootShapeElement.class.getSimpleName();
    private int mLevel = 0;
    private int mIntrinsicWidth;
    private int mIntrinsicHeight;
    private int[] mStateSet = new int[0];

    private WeakReference<Callback> mHmCallback = null;

    public int getIntrinsicWidth() {
        return -1;
    }

    public void setHmCallback(Callback callback){
        mHmCallback = callback!=null ?new WeakReference<>(callback):null;
    }

    public Callback getHmCallback(){
        return mHmCallback!=null? mHmCallback.get():null;
    }

    @Override
    public boolean setVisible(boolean visible, boolean restart) {
        boolean changed = super.setVisible(visible, restart);
        if(changed) {
            invalidateSelf();
        }
       return  changed;
    }

    @Override
    public void setBounds(Rect bounds) {
        super.setBounds(bounds);
    }

    @Override
    public void setBounds(int left, int top, int right, int bottom) {
        Rect oldBounds = getBounds();
        if (oldBounds.left != left || oldBounds.top != top || oldBounds.right != right || oldBounds.bottom != bottom) {
            if (!oldBounds.isEmpty()) {
                // first invalidate the previous bounds
                invalidateSelf();
            }
            super.setBounds(left, top, right, bottom);
            onBoundsChange(getBounds());
        }
    }

    @Override
    public void setColorMatrix(ColorMatrix matrix) {
        super.setColorMatrix(matrix);
    }

    public void setIntrinsicWidth(int intrinsicWidth) {
        this.mIntrinsicWidth = intrinsicWidth;
    }

    public int getIntrinsicHeight() {
        return -1;
    }

    public void setIntrinsicHeight(int intrinsicHeight) {
        this.mIntrinsicHeight = intrinsicHeight;
    }

    public int getLevel() {
        return mLevel;
    }

    public boolean setLevel(int level) {
        if (mLevel != level) {
            mLevel = level;
            return onLevelChange(level);
        }
        return false;
    }

    public boolean onLevelChange(int level){
        return false;
    }

    public void invalidateSelf(){
        //LogUtil.error(TAG,"canvas invalidateSelf ");
        final Callback callback = getHmCallback();
        if(callback!=null){
            callback.invalidateDrawable(this);
        }else{
            //LogUtil.error(TAG,"canvase invalidateSelf callback is null");
        }
    }

    public void scheduleSelf(@NonNull Runnable what, long when) {
        //LogUtil.error(TAG,"canvas scheduleSelf :"+getClass().getSimpleName());
        final Callback callback = getHmCallback();
        if (callback != null) {
            //LogUtil.error(TAG,"canvas scheduleSelf A:"+getClass().getSimpleName());
            callback.scheduleDrawable(this, what, when);
        }else{
            //LogUtil.error(TAG,"canvas scheduleSelf call back is null:"+getClass().getSimpleName());
        }
    }

    public void unscheduleSelf(@NonNull Runnable what) {
        //LogUtil.error(TAG,"canvas unscheduleSelf ");
        final Callback callback = getHmCallback();
        if(callback!=null){
            callback.unscheduleDrawable(this,what);
        }else{
            //LogUtil.error(TAG,"canvas unscheduleSelf callback is null");
        }
    }
    protected void onBoundsChange(Rect bounds) {
        // Stub method.
    }
    public abstract void setColorFilter(@Nullable ColorFilter colorFilter);

    public boolean setState(@NonNull final int[] stateSet) {
        if (!Arrays.equals(mStateSet, stateSet)) {
            mStateSet = stateSet;
            return onStateChange(stateSet);
        }
        return false;
    }
    protected boolean onStateChange(int[] state) {
        return false;
    }

}
